package e.odbo.data.utils;


import e.odbo.data.generator.Generator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;


public class FileUtils {

    public static final Logger logger= LoggerFactory.getLogger(FileUtils.class);


    //功能，拷贝源文件夹下的二级子目录到目标文件夹,有同名重命名功能
    public static void dirCopyWithRename(String srcDir,String distDir) throws IOException {
        File src=new File(srcDir);
        if(!src.exists()) {
            logger.info("源文件目录不存在，退出。。");
            return;
        }

        if(src.isFile()){
            logger.info("输入了文件，本命令只对文件夹有效。。。");
            return;
        }

        long start = System.nanoTime();
        List<String> distdirNames=new ArrayList<>();
        File dist=new File(distDir);
        if(!dist.exists())
            dist.mkdirs();

        for(File listDir:dist.listFiles()) {
            logger.info("初始化存在对比队列。。。");
            if (listDir.isDirectory())
                if (!distdirNames.contains(listDir.getName()))
                    distdirNames.add(listDir.getName());
        }

        int countCopyDir=0;
        int eqNum=0;
        String roundName=null;
        Path toPath=null;
        for(File outDir:src.listFiles()){
            if(outDir.isFile())
                continue;
            logger.info("进入文件夹:" + outDir.getName());
            for(File listDir:outDir.listFiles()) {
                if(listDir.isFile())
                    continue;
                roundName = listDir.getName();
                if (distdirNames.contains(roundName)) {
                    roundName = roundName + "_" + new Random().nextInt(1000);
                    logger.info("发现同名文件夹:" + listDir.getName() + "，进行重命名为:" + roundName);
                    eqNum++;
                }
                toPath = new File(dist.getPath() +File.separatorChar+ roundName).toPath();
                logger.info("正在拷贝文件夹:" + listDir.toString() + "到:" + toPath.toString());
                distdirNames.add(roundName);
                copyFolder(listDir.getPath().toString(),toPath.toString(),null);
                countCopyDir++;
            }
        }
        long end = System.nanoTime();
        logger.info("本次拷贝完成，共拷贝："+countCopyDir+"个文件夹，其中重命名了："+eqNum+"个件夹，用时："+(end-start)/1000+" 秒");
    }


    public static void copyFolder(String srcFolder, String destFolder, final String fileType)
            throws IOException {
        long startTime = System.currentTimeMillis();
        final Path srcPath = Paths.get(srcFolder);
        // 这里多创建一级，就解决了没有外壳的问题
        //final Path destPath = Paths.get(destFolder, srcPath.toFile().getName());

        final Path destPath = Paths.get(destFolder);
        // 检查源文件夹是否存在
        if (Files.notExists(srcPath)) {
            logger.error("源文件夹不存在");
            System.exit(1);
        }
        // 如果目标目录不存在，则创建
        if (Files.notExists(destPath)) {
            Files.createDirectories(destPath);
        }

        // 这里是官方例子的开头，可能是针对大文件处理设置的参数
        // Files.walkFileTree(srcPath,      EnumSet.of(FileVisitOption.FOLLOW_LINKS),
        // Integer.MAX_VALUE, new SimpleFileVisitor<Path>() {}
        //简化后的开头
        Files.walkFileTree(srcPath, new SimpleFileVisitor<Path>() {
            // 官方还调用了专门的文件夹处理，这里没使用
            // public FileVisitResult preVisitDirectory(Path dir,
            // BasicFileAttributes attrs) throws IOException {return null;}
            @Override
            // 文件处理，将文件夹也一并处理，简洁些
            public FileVisitResult visitFile(Path file,
                                             BasicFileAttributes attrs) throws IOException {
                if(!file.toFile().isDirectory()&&null!=fileType&&!file.toString().toLowerCase().endsWith(fileType))
                    return FileVisitResult.CONTINUE;
                Path dest = destPath.resolve(srcPath.relativize(file));
                // 如果说父路径不存在，则创建
                if (Files.notExists(dest.getParent())) {
                    Files.createDirectories(dest.getParent());
                }
                Files.copy(file, dest);
                return FileVisitResult.CONTINUE;
            }
        });
        long endTime = System.currentTimeMillis();
        logger.info("文件夹复制成功!耗时：" + (endTime - startTime) + "ms");
    }

    // 删除文件夹
    public static void deleteFolder(String Foleder) throws IOException {
        Path start = Paths.get(Foleder);
        if (Files.notExists(start)) {
            throw new IOException("文件夹不存在！");
        }

        Files.walkFileTree(start, new SimpleFileVisitor<Path>() {
            @Override //构成了一个内部类
            // 处理文件
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                Files.delete(file);
                return FileVisitResult.CONTINUE;
            }

            @Override
            // 再处理目录
            public FileVisitResult postVisitDirectory(Path dir, IOException e)
                    throws IOException {
                if (e == null) {
                    Files.delete(dir);
                    return FileVisitResult.CONTINUE;
                } else {
                    throw e;
                }
            }
        });
        System.out.println("删除成功！");
    }



    public static void copyFolderWithRenameAndFileType(String srcFolder, String destFolder,String fileType)throws IOException {
        File src=new File(srcFolder);
        if(!src.exists()) {
            logger.info("源文件目录不存在，退出。。");
            return;
        }

        if(src.isFile()){
            logger.info("输入了文件，本命令只对文件夹有效。。。");
            return;
        }

        long start = System.nanoTime();
        List<String> distdirNames=new ArrayList<>();
        File dist=new File(destFolder);
        if(!dist.exists())
            dist.mkdirs();

        int countCopyDir=0;

        for(File outDir:src.listFiles()){
            if(outDir.isFile())
                continue;
        logger.info("进入文件夹:" + outDir.getName());

        copyFolder(outDir.getPath().toString(), destFolder,fileType);
        countCopyDir++;
        }
        long end = System.nanoTime();
        logger.info("本次拷贝完成，共拷贝："+countCopyDir+"个文件目录，其中重命名了："+"个件夹，用时："+(end-start)/1000+" 秒");
    }



    public static void main(String[] args) {
        String srcDir="/Users/wushunlian/Downloads/font/base";
        String distDir="/Users/wushunlian/Downloads/font/font";

        try {
            //dirCopy(srcDir,distDir);
            copyFolderWithRenameAndFileType(srcDir,distDir,".ttf");
        } catch (IOException e) {
            logger.error("拷贝目录出错了："+e.getMessage());
            e.printStackTrace();
        }
    }
}
